/*
 * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
 *
 * Licensed under the Aduna BSD-style license.
 */
 
package edu.tju.commons.concurrent;

import java.io.PrintStream;
import java.util.Date;
import java.util.Map;

/**
 * Thread-related utility methods.
 */
public class ThreadUtil {

	/**
	 * Dumps the track traces of all live Threads to System.out.
	 */
	public static void dumpAllStacks() {
		dumpAllStacks(System.out);
	}

	/**
	 * Dumps the track traces of all live Threads to the specified PrintStream.
	 * 
	 * @param stream
	 *        The PrintStream to which all stack traces will be written.
	 */
	public static void dumpAllStacks(PrintStream stream) {
		stream.println("All current live threads (" + new Date().toString() + "):\n");
		
		Map<Thread, StackTraceElement[]> stackTraces = Thread.getAllStackTraces();
		for (Thread thread : stackTraces.keySet()) {
			stream.print("Thread[name=");
			stream.print(thread.getName());
			stream.print(",id=");
			stream.print(thread.getId());
			stream.print(",priority=");
			stream.print(getPriorityDescription(thread));
			stream.print(",group=");
			stream.print(thread.getThreadGroup().getName());
			stream.println("]");

			for (StackTraceElement element : stackTraces.get(thread)) {
				stream.print("\tat ");
				stream.println(element);
			}
			
			stream.println();
		}
	}

	private static String getPriorityDescription(Thread thread) {
		int priority = thread.getPriority();
		if (priority == Thread.MIN_PRIORITY) {
			return priority + " (MIN_PRIORITY)";
		}
		else if (priority == Thread.MAX_PRIORITY) {
			return priority + " (MAX_PRIORITY)";			
		}
		else if (priority == Thread.NORM_PRIORITY) {
			return priority + " (NORM_PRIORITY)";
		}
		else {
			return String.valueOf(priority);
		}
	}
}
